import React, {useState} from 'react';
import {Table, Input, InputNumber, Form, Button} from 'acud';
import { useRequest } from 'ahooks';
import axios from 'axios';

const BaseUrl = process.env.REACT_APP_API_URL;

interface Item {
    key: string;
    name: string;
    age: number;
    address: string;
    isNew?: boolean;
}

const originData: Item[] = [];
for (let i = 0; i < 6; i++) {
    originData.push({
        key: i.toString(),
        name: `Edrward ${i}`,
        age: 32,
        address: `London Park no. ${i}`,
    });
}
interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
    editing: boolean;
    dataIndex: string;
    title: any;
    inputType: 'number' | 'text';
    record: Item;
    index: number;
    children: React.ReactNode;
}

const EditableCell: React.FC<EditableCellProps> = ({
    editing,
    dataIndex,
    title,
    inputType,
    record,
    index,
    children,
    ...restProps
}) => {
    const inputNode = inputType === 'number' ? <InputNumber size={'small'} /> : <Input size={'small'} />;

    return (
        <td {...restProps}>
            {editing ? (
                <Form.Item
                    name={dataIndex}
                    style={{margin: 0}}
                    rules={[
                        {
                            required: true,
                            message: `Please Input ${title}!`,
                        },
                    ]}
                >
                    {inputNode}
                </Form.Item>
            ) : (
                children
            )}
        </td>
    );
};

const EditableTable = () => {
    const [form] = Form.useForm();
    const [data, setData] = useState<any>(originData);
    const [editingKey, setEditingKey] = useState('');

    useRequest(() => axios.get('http://localhost:3004/expand'), {
        onSuccess(res) {
            setData(res.data);
        }
    });

    const isEditing = (record: Item) => record.key === editingKey;

    const edit = (record: Partial<Item> & {key: React.Key}) => {
        form.setFieldsValue({name: '', age: 0, address: '', ...record});
        setEditingKey(record.key);
    };

    const cancel = () => {
        setEditingKey('');
    };

    const add = () => {
        const newKey = data.length.toString();
        const newData = [...data];
        const row = {name: '', age: 0, address: '', key: newKey, isNew: true};
        newData.unshift(row);
        setData(newData);
        edit(row);        
    };

    const save = async (key: React.Key) => {
        try {
            const row = (await form.validateFields()) as Item;

            const newData = [...data];
            const index = newData.findIndex((item) => key === item.key);
            if (index > -1) {
                const item = newData[index];
                newData.splice(index, 1, {
                    ...item,
                    ...row,
                });
                setData(newData);
                setEditingKey('');
            } else {
                newData.push(row);
                setData(newData);
                setEditingKey('');
            }
        } catch (errInfo) {
            console.log('Validate Failed:', errInfo);
        }
    };

    const columns = [
        {
            title: 'name',
            dataIndex: 'name',
            key: 'name',
            width: '25%',
            editable: true,
        },
        {
            title: 'age',
            dataIndex: 'age',
            key: 'age',
            width: '15%',
            editable: true,
        },
        {
            title: 'address',
            dataIndex: 'address',
            width: '40%',
            key: 'address',
            editable: true,
        },
        {
            title: 'operation',
            dataIndex: 'operation',
            key: 'operation',
            render: (_: any, record: Item) => (
                <Table.Space key="save">
                    <Button size={'small'} onClick={() => save(record.key)}>
                        Save
                    </Button>
                    <a style={{lineHeight: '24px'}} onClick={cancel}>
                        Cancel
                    </a>
                </Table.Space>
            ),
        },
    ];

    const mergedColumns = columns.map((col) => {
        if (!col.editable) {
            return col;
        }
        return {
            ...col,
            onCell: (record: Item) => ({
                record,
                inputType: col.dataIndex === 'age' ? 'number' : 'text',
                dataIndex: col.dataIndex,
                title: col.title,
                editing: isEditing(record),
            }),
        };
    });

    const rowSelection = {
        onChange: (selectedRowKeys: any, selectedRows: any) => {
            console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
        },
        onSelect: (record: any, selected: any, selectedRows: any) => {
            console.log(record, selected, selectedRows);
        },
        onSelectAll: (selected: any, selectedRows: any, changeRows: any) => {
            console.log(selected, selectedRows, changeRows);
        }
    };
    return (
        <Form form={form}>
            <Table
                components={{
                    body: {
                        cell: EditableCell,
                    },
                }}
                // rowSelection={{ ...rowSelection }}
                dataSource={[data?.result]}
                columns={mergedColumns}
                rowKey="id"
                rowClassName="editable-row"
                pagination={{
                    onChange: cancel,
                }}
            />
            <Button style={{marginTop: 10}} type="primary" disabled={editingKey !== ''} onClick={add}>
                新增
            </Button>
        </Form>
    );
};

export default EditableTable;
